package com.fm.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.ibatis.javassist.tools.framedump;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.fm.MDA;
import com.fm.service.dto.Attachment;
import com.fm.service.dto.AttachmentComponent;
import com.fm.service.file.smo.IFileOperSMO;
import com.fm.service.file.smo.Office2PdfSMOImpl;
import com.fm.util.DateUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Controller
@RequestMapping("fileController")
public class FileController {

	private static final Logger logger = LogManager.getLogger(FileController.class);
	
	@Autowired
	private IFileOperSMO fileOperSMO;
	@Autowired
	private Office2PdfSMOImpl office2PdfSMOImpl;
	@Autowired
	private Environment env;//执行环境
	
	@RequestMapping("/test")
	@ResponseBody
	public String test(@RequestBody String jsonString) {
		logger.debug(jsonString);

		return "{}";
	}
    /**
     * 多组件多文件上传
     * @param request
     */
	@RequestMapping(value = "batchUploadFiles", method = RequestMethod.POST)
	@ResponseBody
	public String handleFileUpload(HttpServletRequest request) {
		
		Map<String, Object> resultMap = new JSONObject();
		
		try {
			
			resultMap = fileOperSMO.batchUploadFiles((MultipartHttpServletRequest)request);
			
		} catch (Exception e) {
			//文件上传失败
			logger.error("文件上传报错。。。"+e.getMessage());
			resultMap.put("resultCode", "-1");
			resultMap.put("resultMsg", e.getMessage());
		}	
		
		return JSONObject.fromObject(resultMap).toString();
	}

	@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
	public void getDownload(HttpServletRequest req,HttpServletResponse res) {
		String fileName = req.getParameter("fileName");
		String realName = req.getParameter("realName");
		if(realName == null || "".equals(realName)){
			realName = fileName;
		}
//		else{
//			try {
//				realName = new String(name.getBytes("iso8859-1"),"utf-8");
//			} catch (UnsupportedEncodingException e) {
//				logger.error("文件名转换异常");
//				realName = fileName;
//			}
//		}
		res.setHeader("content-type", "application/octet-stream");
		res.setContentType("application/octet-stream");
		res.setHeader("Content-Disposition", "attachment;filename=" + realName);
		byte[] buff = new byte[1024];
		BufferedInputStream bis = null;
		OutputStream os = null;
		try {
			os = res.getOutputStream();
			//获取文件后缀
			String surfix = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length());
			bis = new BufferedInputStream(new FileInputStream(new File(env.getProperty(MDA.KEY_ABSOLUTE_PATH.get(MDA.FILE_SUFFIX.get(surfix.toLowerCase())).toString()) + "//"+MDA.FILE_SUFFIX.get(surfix.toLowerCase())+"//"  + fileName)));
			int i = bis.read(buff);
			while (i != -1) {
				os.write(buff, 0, buff.length);
				os.flush();
				i = bis.read(buff);
			}
		} catch (IOException e) {
			logger.error("文件下载报错。。。"+e.getMessage());
		} finally {
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					logger.error("文件下载报错。。。关闭输入流报错..."+e.getMessage());
				}
			}
		}
	}
	
	@RequestMapping(value = "/downloadFile", method = RequestMethod.POST)
	public void postDownload(HttpServletRequest req,HttpServletResponse res) {
		String fileName = req.getParameter("fileName");
		//res.setHeader("content-type", "application/octet-stream");
		//res.setContentType("application/octet-stream");
		//res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
		byte[] buff = new byte[1024];
		BufferedInputStream bis = null;
		OutputStream os = null;
		try {
			os = res.getOutputStream();
			//获取文件后缀
			String surfix = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length());
			bis = new BufferedInputStream(new FileInputStream(new File(env.getProperty(MDA.KEY_ABSOLUTE_PATH.get(MDA.FILE_SUFFIX.get(surfix.toLowerCase())).toString())+ "//"+MDA.FILE_SUFFIX.get(surfix.toLowerCase())+"//"  + fileName)));
			int i = bis.read(buff);
			while (i != -1) {
				os.write(buff, 0, buff.length);
				os.flush();
				i = bis.read(buff);
			}
		} catch (IOException e) {
			logger.error("文件下载报错。。。"+e.getMessage());
		} finally {
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					logger.error("文件下载报错。。。关闭流报错..."+e.getMessage());
				}
			}
		}
	}
	@RequestMapping(value = "/fileToPdf", method = RequestMethod.GET)
	public void fileToPdfGet(HttpServletRequest req,HttpServletResponse res) {
		String fileName = req.getParameter("fileName");
		//res.setHeader("content-type", "application/octet-stream");
		//res.setContentType("application/octet-stream");
		//res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
		
	     File pdffile = new File(fileName+".pdf");
	    String surfix = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length());
	     office2PdfSMOImpl.convertTo(new File(env.getProperty(MDA.KEY_ABSOLUTE_PATH.get(MDA.FILE_SUFFIX.get(surfix.toLowerCase())).toString()) + "//"+MDA.FILE_SUFFIX.get(surfix.toLowerCase())+"//"  + fileName), pdffile);  
		
		byte[] buff = new byte[1024*3];
		BufferedInputStream bis = null;
		OutputStream os = null;
		try {
			os = res.getOutputStream();
			//获取文件后缀
			bis = new BufferedInputStream(new FileInputStream(pdffile));
			int i = bis.read(buff);
			while (i != -1) {
				os.write(buff, 0, buff.length);
				os.flush();
				i = bis.read(buff);
			}
		} catch (IOException e) {
			logger.error("文件在线查看转换报错。。。"+e.getMessage());
		} finally {
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					logger.error("文件在线查看转换报错。。。流关闭报错..."+e.getMessage());
				}
			}
		}
	}
	@RequestMapping(value = "/fileToPdf", method = RequestMethod.POST)
	public void fileToPdfPost(HttpServletRequest req,HttpServletResponse res) {
		String fileName = req.getParameter("fileName");
		res.setHeader("content-type", "application/octet-stream");
		res.setContentType("application/octet-stream");
		res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
		
	     File pdffile = new File(fileName+".pdf");
	    String surfix = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length());
	     office2PdfSMOImpl.convertTo(new File(env.getProperty(MDA.KEY_ABSOLUTE_PATH.get(MDA.FILE_SUFFIX.get(surfix.toLowerCase())).toString()) + "//"+MDA.FILE_SUFFIX.get(surfix.toLowerCase())+"//"  + fileName), pdffile);  
		
		byte[] buff = new byte[1024*3];
		BufferedInputStream bis = null;
		OutputStream os = null;
		try {
			os = res.getOutputStream();
			//获取文件后缀
			bis = new BufferedInputStream(new FileInputStream(pdffile));
			int i = bis.read(buff);
			while (i != -1) {
				os.write(buff, 0, buff.length);
				os.flush();
				i = bis.read(buff);
			}
		} catch (IOException e) {
			logger.error("文件在线查看转换报错。。。"+e.getMessage());
		} finally {
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					logger.error("文件在线查看转换报错。。。流关闭报错..."+e.getMessage());
				}
			}
		}
		logger.debug("success");
	}
	@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
	@ResponseBody
	public String testUploadFile(HttpServletRequest req, MultipartHttpServletRequest multiReq) {
		
		JSONObject result = new JSONObject();
		try {
			//上传时，没有附件
			Iterator<String> fileNames = multiReq.getFileNames();
			if(fileNames == null || !fileNames.hasNext()){
				logger.warn("== uploadFile , no file found. ");
				result.element("resultCode", "-1");
				result.element("resultMsg", "no file found");
				return  result.toString();
			}
			
			//获取附件名
			String fileName = "";
			while (fileNames.hasNext()) {
				fileName = (String) fileNames.next();
				break;	
			}
			
			//获取附件文件
			MultipartFile multipartFile = multiReq.getFile(fileName);
			
			// 获取上传文件的路径
			String uploadFilePath = multipartFile.getOriginalFilename();
			logger.debug("==uploadFlePath : " + uploadFilePath);
			// 截取上传文件的文件名
			String uploadFileName = uploadFilePath.substring(uploadFilePath.lastIndexOf('\\') + 1,
					uploadFilePath.indexOf('.'));
			logger.debug("==multiReq.getFile() : " + uploadFileName);
			// 截取上传文件的后缀
			String uploadFileSuffix = uploadFilePath.substring(uploadFilePath.indexOf('.') + 1, uploadFilePath.length());
			logger.debug("==uploadFileSuffix : " + uploadFileSuffix);
			
			
			//TODO 文件后缀、大小、格式等校验
			
			
			FileOutputStream fos = null;
			FileInputStream fis = null;
			File outFile = null;
			try {
				
				//TODO 具体上传路劲待规划
				
				outFile = new File(env.getProperty(MDA.KEY_ABSOLUTE_PATH.get(MDA.FILE_SUFFIX.get(uploadFileSuffix.toLowerCase())).toString()) + "//uploadFiles//" + uploadFileName + "." + uploadFileSuffix);
				
				fis = (FileInputStream) multipartFile.getInputStream();
				fos = new FileOutputStream(outFile);
				byte[] temp = new byte[1024];
				int i = fis.read(temp);
				while (i != -1) {
					fos.write(temp, 0, temp.length);
					fos.flush();
					i = fis.read(temp);
				}
				
				result.element("resultCode", "0");
				result.element("resultMsg", "file upload success.");
				
				JSONObject reObject = new JSONObject();
				reObject.element("fileName", uploadFileName + uploadFileSuffix);//文件全称
				reObject.element("uploadFileName", uploadFileName);//文件名
				reObject.element("uploadFileSuffix", uploadFileSuffix);//文件后缀
				reObject.element("path", outFile.getPath());
				reObject.element("absoluteUrlPath", outFile.getAbsolutePath());
				reObject.element("fileSize", multipartFile.getSize());
				reObject.element("uploadDt", DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
				
				result.element("result", reObject);
				
			} catch (IOException e) {
				//读取文件流失败
				result.element("resultCode", "-1");
				result.element("resultMsg", "file read error.");
				logger.error("file read error. " + e.getMessage());
			} finally {
				if (fis != null) {
					try {
						fis.close();
					} catch (IOException e) {
						logger.error(e.getMessage());
					}
				}
				if (fos != null) {
					try {
						fos.close();
					} catch (IOException e) {
						logger.error(e.getMessage());
					}
				}
			}
		} catch (Exception e) {
			//文件上传失败
			result.element("resultCode", "-1");
			result.element("resultMsg", "file upload error.");
			logger.error("file upload error。 "+e.getMessage());
		}
		
		return result.toString();
	}

}
